package com.tanqidi.arcgisandroid.ui.layerConfig

import android.os.Bundle
import android.text.TextUtils
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.tabs.TabLayoutMediator
import com.tanqidi.arcgisandroid.R
import com.tanqidi.arcgisandroid.base.utils.getSPUtils
import com.tanqidi.arcgisandroid.base.utils.showToast
import com.tanqidi.arcgisandroid.data.featureServer.bean.ArcgisFeatureLayer
import com.tanqidi.arcgisandroid.data.layerConfig.Field
import com.tanqidi.arcgisandroid.data.layerConfig.LayerConfig
import com.tanqidi.arcgisandroid.data.layerConfig.LayerConfig.Companion.TYPE_POINT
import com.tanqidi.arcgisandroid.data.layerConfig.LayerConfig.Companion.TYPE_POLYGON
import com.tanqidi.arcgisandroid.data.layerConfig.LayerConfig.Companion.TYPE_POLYLINE
import com.tanqidi.arcgisandroid.data.project.Project
import com.tanqidi.arcgisandroid.databinding.FragmentLayerConfigBinding
import com.tanqidi.arcgisandroid.databinding.ItemDialogInputBinding
import com.tanqidi.arcgisandroid.ui.layerConfig.subLayer.SubLayerAdapter
import com.tanqidi.arcgisandroid.ui.layerConfig.subLayer.SubLayerFragment
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch

@AndroidEntryPoint
class LayerConfigFragment : Fragment() {

    private lateinit var binding:FragmentLayerConfigBinding
    private val layerConfigViewModel by viewModels<LayerConfigViewModel>()
    private val args by navArgs<LayerConfigFragmentArgs>()
    private lateinit var project: Project

    private val subFragmentList = mutableListOf<SubLayerFragment>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = FragmentLayerConfigBinding.inflate(layoutInflater)
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        initTopBar()
        initViewEvent()
        initLiveData()
        initTabLayoutAndViewPage()
        return binding.root
    }

    /**
     * 这里是给subFragment调用的，viewPage中的子页面跳转不过去的
     */
    fun goFieldConfigFragment(projectName:String, layerName:String){
        val action = LayerConfigFragmentDirections.actionLayerConfigFragmentToFieldConfigFragment(projectName, layerName)
        findNavController().navigate(action)
    }

    fun flushTabCount(type: String, count: Int) {
        project = layerConfigViewModel.getProjectByName(args.projectName)

        val index = when(type) {
            TYPE_POINT -> {0}
            TYPE_POLYLINE -> {1}
            TYPE_POLYGON -> {2}
            else -> {0}
        }
        val orCreateBadge = binding.tabLayout.getTabAt(index)!!.orCreateBadge
        //如果只有0个，就不用显示出来了
        if (count == 0) {
            orCreateBadge.isVisible = false
            orCreateBadge.clearNumber()
        } else {
            orCreateBadge.isVisible = true
            orCreateBadge.number = count
        }
    }

    private fun initTabLayoutAndViewPage() {

        subFragmentList.apply {
            clear()
            add(SubLayerFragment.newInstance(TYPE_POINT, args.projectName))
            add(SubLayerFragment.newInstance(TYPE_POLYLINE, args.projectName))
            add(SubLayerFragment.newInstance(TYPE_POLYGON, args.projectName))
        }
        val tabLayout = binding.tabLayout
        val viewPager2 = binding.viewPager2

        val subLayerAdapter = SubLayerAdapter(this, subFragmentList)
        //因为只有三个页面所以不做缓存，全部显示出来
        viewPager2.offscreenPageLimit = subFragmentList.size
        viewPager2.isSaveEnabled = false

        viewPager2.adapter = subLayerAdapter
        TabLayoutMediator(tabLayout, viewPager2) { tab, position ->
            //这里嘛，因为上面newInstance已经把title标题传入了，这里直接从argument里面拿出来用就行了
            tab.text = subFragmentList[position].requireArguments().get(SubLayerFragment.LAYER_TYPE) as String
        }.attach()
    }

    private fun initViewEvent() {
        binding.addFloatingActionButton.setOnClickListener {
            val dialogBinding = ItemDialogInputBinding.inflate(layoutInflater).apply {
                val url = getSPUtils().getString(getString(R.string.feature_server_url))
                if(!TextUtils.isEmpty(url)){
                    textInputEditText.setText(url)
                }
            }
            val dialog = MaterialAlertDialogBuilder(requireContext())
                .setTitle("新建图层")
                .setView(dialogBinding.root)
                .show()

            dialogBinding.apply {
                accept.setOnClickListener {
                    val content = textInputEditText.text.toString().trim()

                    if(TextUtils.isEmpty(content)){
                        textInputLayout.error = "内容不可为空"
                    } else {
                        //判断图层名字是否是url，如果是url就弹窗选择
                        if(content.startsWith("http") || content.startsWith("https")){
                            getSPUtils().put(getString(R.string.feature_server_url), content)

                            //是url
                            lifecycleScope.launch {
                                kotlin.runCatching {
                                    val arcgisFeatureServer = layerConfigViewModel.getArcgisFeatureServerByUrl(content)
                                    //拿project来判断一下，是不是已经识别过了，再次弹窗直接选中
                                    val project = layerConfigViewModel.getProjectByName(project.name)
                                    val checkedItems = mutableListOf<Boolean>()

                                    val layerNameMap = linkedMapOf<String, ArcgisFeatureLayer>()
                                    arcgisFeatureServer.layers?.forEachIndexed { index, arcgisFeatureLayer ->
                                        layerNameMap[index.toString()+"、"+arcgisFeatureLayer.name.toString()] = arcgisFeatureLayer

                                        checkedItems.add(project.layers.filter { it.name == arcgisFeatureLayer.name }.isNotEmpty())
                                    }
                                    val nameList = layerNameMap.keys.toTypedArray()

                                    val multiChoiceList = mutableListOf<ArcgisFeatureLayer>()
                                    MaterialAlertDialogBuilder(requireContext())
                                        .setTitle("要素图层列表")
                                        .setNeutralButton(R.string.cancel) { dialog, which -> }
                                        .setPositiveButton(R.string.accept) { dialog, which ->
                                            if(multiChoiceList.isNotEmpty()){
                                                lifecycleScope.launch {
                                                    batchGenerateLayerConfig(content, multiChoiceList)
                                                }
                                            }
                                        }
                                        .setMultiChoiceItems(nameList, checkedItems.toBooleanArray()) { dialog, which, checked ->
                                            val arcgisFeatureLayer = layerNameMap[nameList[which]]
                                            if(checked){
                                                multiChoiceList.add(arcgisFeatureLayer!!)
                                            } else {
                                                multiChoiceList.remove(arcgisFeatureLayer!!)
                                            }
                                        }.show()

                                    dialog.dismiss()
                                }.onFailure {
                                    it.message?.let { it1 -> showToast(it1) }
                                }
                            }


                        } else {
                            //是名字
                            val currentSubFragment = subFragmentList[binding.tabLayout.selectedTabPosition]
                            val type = currentSubFragment.requireArguments().get(SubLayerFragment.LAYER_TYPE) as String
                            project.layers.add(LayerConfig().apply {
                                this.type = type
                                name = content
                            })
                            //既然project放了一个新的layer图层了，覆盖一下本地的配置文件
                            layerConfigViewModel.saveProject(project)
                            //创建完了让子sub的fragment重新加载一下显示出来
                            showToast("创建成功")
                            currentSubFragment.flushData()
                            dialog.dismiss()
                        }

                    }
                }
            }
        }
    }

    private suspend fun batchGenerateLayerConfig(featureServerUrl:String, multiChoiceList: List<ArcgisFeatureLayer>) {
        multiChoiceList.forEachIndexed { index, arcgisFeatureLayer ->
            val featureLayerUrl = featureServerUrl + "/" + arcgisFeatureLayer.id
            val arcgisFeatureLayer = layerConfigViewModel.getArcgisFeatureLayerByUrl(featureLayerUrl)
            val layerConfig = LayerConfig().apply {
                this.name = arcgisFeatureLayer.name!!
                this.id = arcgisFeatureLayer.id
                this.type = when(arcgisFeatureLayer.geometryType){
                    ArcgisFeatureLayer.esriGeometryPoint -> TYPE_POINT
                    ArcgisFeatureLayer.esriGeometryPolyline -> TYPE_POLYLINE
                    ArcgisFeatureLayer.esriGeometryPolygon -> TYPE_POLYGON
                    else -> TYPE_POINT
                }
                //将拼接得到的featureLayerUrl也设置进去，这个后面离线的时候需要用到它
                // TODO: 我的arcgis server是内网环境，如果使用https会出现ssl不信任情况，我没法子绕过去只能使用http不然会连接不上
//                this.featureLayerUrl = featureLayerUrl.replace("https", "http")
                this.featureLayerUrl = featureLayerUrl
            }
            /**
             * 初始化字段之前需要字段排除一下，OBJECTID和GLOBALID都需要排除，刚好这些字段都是无法编辑的，过滤一下得到可以编辑内容的字段就是我们自己的字段了
             */
            arcgisFeatureLayer.fields?.filter { it.editable }?.forEachIndexed { index, arcgisField ->
                layerConfig.fields.add(Field().apply {
                    this.alias = arcgisField.alias!!
                    this.field = arcgisField.name!!
                })
            }
            project.layers.add(layerConfig)
            //既然project放了一个新的layer图层了，覆盖一下本地的配置文件
            layerConfigViewModel.saveProject(project)
        }
        //创建完了让子sub的fragment重新加载一下显示出来
        subFragmentList.forEachIndexed { index, subLayerFragment ->
            subLayerFragment.flushData()
        }

    }

    private fun initTopBar(){
        //返回键
        binding.topAppBar.setNavigationOnClickListener {
            findNavController().navigateUp()
        }
    }

    private fun initLiveData(){

    }
}